package com.computec.tray;

/*
 * Copyright (C) 2004 Sun Microsystems, Inc. All rights reserved. Use is
 * subject to license terms.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the Lesser GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.jdesktop.jdic.tray.SystemTray;
import org.jdesktop.jdic.tray.TrayIcon;

import com.computec.tray.constantes.ConstantesGenerales;


public class Tray implements ActionListener, ItemListener {

    SystemTray tray = SystemTray.getDefaultSystemTray();
    TrayIcon ti;
    JFrame frame;
    ImageIcon greenIcon = null;
    ImageIcon redIcon =null;
    boolean estadoAnterior=true;
    boolean isServerAlive=false;
    boolean enviarCorreo=false;
    boolean reinicioPortal=false;
    int failTimes=0;
    int maxFailTimes=0;
    Email emailClass=Email.getInstance();
    ConstantesGenerales constantesGenerales;
    String nombreGlobalUrl="";
    boolean reinicioManual=false;
    private static Logger log = Logger.getLogger(Tray.class);

    
    public Tray(String[] args) {
    	ConstantesGenerales.getInstance();
    	
    	//Numero maximo de fallas permitidas al scanear url
    	try {
    		maxFailTimes=Integer.parseInt(constantesGenerales.FAIL_TIMES);
		} catch (NumberFormatException e1) {
			maxFailTimes=3;
		}
		
		//**********************************************************************
		//REINICIO AUTOMATICO DE PORTAL RADAR+
		String horaReinicio=constantesGenerales.HORA_REINICIO_PORTAL;
	        
        
      
        int tmpHora=0;
        int tmpMin=0;
        try{       
        	
            if(horaReinicio!=null && !horaReinicio.equals("0")){
                String [] horaMin=horaReinicio.trim().split(":");
                
                if (horaMin!=null && horaMin.length>1){
                	tmpHora=Integer.parseInt(horaMin[0]);
                	tmpMin=Integer.parseInt(horaMin[1]);
                }
                reinicioPortal=true;
            }else{
            	reinicioPortal=false;
            }
        }catch(Exception e){	    
            System.out.println("La hora <"+horaReinicio+"> de ejecucion no tiene el formato correcto, por defecto se corre a las 3:00 ");
            //e.printStackTrace();
            tmpHora=3;
            tmpMin=0;
        }
        
		//**********************************************************************
        final int hora=tmpHora;
        final int min=tmpMin;
		
		
		
        JPopupMenu menu;        
        JMenuItem menuItemQuit;
        JMenuItem menuItemRestart;
	
	 // Check the arguments
        if ((args.length < 3)) 
              throw new IllegalArgumentException("");

	final String nombreUrl=args[0];
	this.nombreGlobalUrl=nombreUrl;
	final String urlServer=args[1];
	
	//ResourceBundle props = ResourceBundle.getBundle("log4j"+nombreUrl+".properties");
	
	Properties p=new Properties();
	try {
		p.load(this.getClass().getResourceAsStream("/log4j"+nombreUrl+".properties"));
	} catch (IOException e1) {		
		e1.printStackTrace();
	}
		
		
		PropertyConfigurator.configure(p);
	
	
//	PropertyConfigurator.configure("log4j"+nombreUrl+".properties");
	
	log.info(nombreGlobalUrl+" - Inicio aplicacion de monitoreo");
	log.info(nombreGlobalUrl+" - Max fail times set to:"+maxFailTimes);
	//Intervalo de milisegundos que el monitor scanea urls
    
	final String timeString=args[2];
	String[] correosArray=null;
	if(args.length>3){		
		int cantCorreos=args.length-3;
		correosArray=new String[cantCorreos];
		int j=3;
		for(int i=0;i<cantCorreos;i++){
			correosArray[i]=args[j];
			j++;
		}
	}
	
	final String[] fCorreosArray=correosArray;

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if( Integer.parseInt(System.getProperty("java.version").substring(2,3)) >=5 )
            System.setProperty("javax.swing.adjustPopupLocationToFit", "false");


        menu = new JPopupMenu("A Menu");
        
        // "Quit" menu item
//        menuItemRestart = new JMenuItem("Restart Server");
//        menuItemRestart.addActionListener(this);
//        menu.add(menuItemRestart);
//        menu.addSeparator();
        menuItemQuit = new JMenuItem("Quit");
        menuItemQuit.addActionListener(this);
        menu.add(menuItemQuit);
        
	greenIcon = new ImageIcon(Tray.class.getResource("images/greenBall.gif"));
	redIcon = new ImageIcon(Tray.class.getResource("images/redBall.gif"));


        ti = new TrayIcon(greenIcon , nombreUrl, menu);

        ti.setIconAutoSize(true);
        ti.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            	frame.setVisible(!frame.isVisible());
            }
        });
        ti.addBalloonActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
           //   JOptionPane.showMessageDialog(null,   "Balloon Message been clicked - TrayIcon", "Message",  JOptionPane.INFORMATION_MESSAGE);
            }
        });
        
        tray.addTrayIcon(ti);

        
        // Construct the GUI for balloon message.
       // frame = new JFrame("Show Balloon Message");
      //  frame.getContentPane().setLayout(new BorderLayout());
      //  frame.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        
      //  JPanel topPanel = new JPanel();
     //   topPanel.setBorder(BorderFactory.createEtchedBorder());
     //   topPanel.setLayout(new BorderLayout());
     //   topPanel.add(new JLabel("Caption: "), BorderLayout.WEST);
     //   final JTextField captionField = new JTextField("JDIC TrayIcon"); 
     //   topPanel.add(captionField, BorderLayout.CENTER);
     //   JPanel typePanel = new JPanel();
     //   final JComboBox typeBox = new JComboBox(new String[]{"INFO", "ERROR", "WARNING", "NONE" });
     //   typePanel.add(new JLabel(" Type:"), BorderLayout.WEST);
     //   typePanel.add(typeBox, BorderLayout.EAST);
     //   topPanel.add(typePanel, BorderLayout.EAST);
     //   frame.getContentPane().add(topPanel, BorderLayout.NORTH);
        
     //   JPanel messagePanel = new JPanel();
     //   messagePanel.setLayout(new BorderLayout());
     //   messagePanel.add(new JLabel("Message:"), BorderLayout.NORTH);
     //   final JTextArea messageArea = new JTextArea(5, 20); 
     //   messageArea.setText("This is a balloon message.\nYou can set the caption, message, \nand message type");
     //   messageArea.setBorder(BorderFactory.createEtchedBorder());
     //   messagePanel.add(messageArea);
     //   frame.getContentPane().add(messagePanel, BorderLayout.CENTER);
        
      //  JPanel buttonPanel = new JPanel();
       // final JButton okButton = new JButton("OK");
      //  final JButton cancelButton = new JButton("Cancel");
       

 	// ActionListener al = new ActionListener(){
	 //		public void actionPerformed(ActionEvent e) {
	 //			if(e.getSource() == cancelButton)
		 //			frame.setVisible(false);
	 //			else if(e.getSource() == okButton){
			 //		ti.displayMessage(captionField.getText(), messageArea.getText(), typeBox.getSelectedIndex());
			 //	}
		 //	}
      //   };
      // okButton.addActionListener(al);
      //cancelButton.addActionListener(al);
      //buttonPanel.add(okButton);
      //buttonPanel.add(cancelButton);
      //frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
      //frame.pack();
      //frame.setLocationRelativeTo(null);
      //frame.setVisible(true);

 	
       final SSHShell shell=new SSHShell();
        
	Thread th=new Thread(new Runnable(){
	    public void run(){			 
		try{
			
		long timeScan=5000;
		
			try{
 		       		timeScan=Long.parseLong(timeString);
			}catch(java.lang.NumberFormatException nex){
				log.error(nombreGlobalUrl+" - "+nex.getMessage());
				timeScan=5000;
			}
			log.info(nombreGlobalUrl+" - Time scan set to:"+timeScan+" millis");
			
		  while(true){
			log.info(nombreGlobalUrl+" - revisando estado servidor."); 	
			isServerAlive=isAliveUrl(urlServer);
			//Si el estado anterior es diferente al estado actual reportar estado
			if(estadoAnterior!=isServerAlive){
				estadoAnterior=isServerAlive;				
				//Si el servidor se encuentra off-line 
				if(!isServerAlive){
					
					failTimes++;
					log.error(nombreGlobalUrl+" - cambio de estado a "+estadoAnterior);
					log.warn(nombreGlobalUrl+" - fail time:"+failTimes);
					
				}else{//Si el servidor paso a estado on-line
					ti.setIcon(greenIcon);
					failTimes=0;
					log.error(nombreGlobalUrl+" - Server On-line.");
					if(fCorreosArray!=null)
						enviarCorreo("Server On-line "+urlServer,fCorreosArray);
				}	
			}else if(!isServerAlive){				
					failTimes++;		
					log.debug(nombreGlobalUrl+" - fail time:"+failTimes);
					
					if(failTimes==maxFailTimes){
						ti.setIcon(redIcon);
						setMensaje("Error","Server off-line "+urlServer,1);
						log.error(nombreGlobalUrl+" - Server off-line.");
						if(fCorreosArray!=null)
							enviarCorreo("Server Off-line "+urlServer,fCorreosArray);
					}
				}				
			Thread.sleep(timeScan);
		  }		
		}catch(java.lang.InterruptedException ix){
			log.error(nombreGlobalUrl+" - "+ix.getMessage());
		    ix.printStackTrace();
		}
	    }   
	});

	th.start();

    }



	//Mostrar mensaje en tray en forma de globo

	public void setMensaje(String title,String pMensjaje,int tipo){
		//{"INFO", "ERROR", "WARNING", "NONE" });
		ti.displayMessage(title, pMensjaje, tipo);
	}

	// Returns just the class name -- no package info.
	protected String getClassName(Object o) {
        	String classString = o.getClass().getName();
	        int dotIndex = classString.lastIndexOf(".");

	        return classString.substring(dotIndex + 1);
	    }

    public void actionPerformed(ActionEvent e) {
        JMenuItem source = (JMenuItem) (e.getSource());
        String s = source.getText();
        if (s.equalsIgnoreCase("Quit")) {
//            System.out.println("Quit menu item selected!");
            log.info(nombreGlobalUrl+" - Fin monitoreo.");
            System.exit(0);
//        }else if(s.equalsIgnoreCase("Restart Server")){
//        	SSHShell shell=new SSHShell();
//        	reinicioManual=true;
//        	if(nombreGlobalUrl.equalsIgnoreCase(constantesGenerales.HOST_NAME_GATEWAY)){
//        		shell.apagarGateway();            	
//            	shell.prenderGateway();
//			}else if(nombreGlobalUrl.equalsIgnoreCase(constantesGenerales.HOST_NAME_PORTAL)){					
//				shell.apagarGateway();
//            	shell.reiniciarPortal();
//            	shell.prenderGateway();
//			}else if(nombreGlobalUrl.equalsIgnoreCase(constantesGenerales.HOST_NAME_PORTAL_DESARROLLO)){
//				shell.reiniciarPortalDesarrollo();
//			}					
//        	reinicioManual=false;
        } else {
            s = "Action event detected." + "\n" + "    Event source: "
                + source + " (an instance of " + getClassName(source) + ")";

//            System.out.println(s);
        }
    }

    public void itemStateChanged(ItemEvent e) {
        JMenuItem source = (JMenuItem) (e.getSource());
        String s = "Item event detected." + "\n" + "    Event source: "
                + source.getText() + " (an instance of " + getClassName(source)
                + ")" + "\n" + "    New state: "
                + ((e.getStateChange() == ItemEvent.SELECTED)
                        ? "selected"
                        : "unselected");

        System.out.println(s);
    }


     //Verifica si una url devuelve informacion html o error

     public boolean isAliveUrl(String arg) {

	boolean serverAlive=false;
        String urlname = "<URL>";
        InputStream in = null;   
        OutputStream out = null;
        String whereAt = "nowhere";
        try {         
            // Set up the streams

            whereAt="before arg fetch";
            urlname = arg;
            whereAt="before URL fetch";
            URL url = new URL(arg);   // Create the URL
            URLConnection uc = url.openConnection();
            uc.setDefaultUseCaches(false);
            uc.setUseCaches(false);
            uc.setRequestProperty("Cache-Control","max-age=0,no-cache");
            uc.setRequestProperty("Pragma","no-cache");
            //uc.setRequestProperty("Cache-Control","no-cache");

            whereAt="before OpenStream ";
            //in = url.openStream();        // Open a stream to it
            in = uc.getInputStream();
          //  whereAt="before System.out ";
	   //    out = System.out;
            
            // Now copy bytes from the URL to the output stream
           // byte[] buffer = new byte[4096];
         //   int bytes_read;
        //    whereAt="before Reading";
            
         //   while((bytes_read = in.read(buffer)) != -1)
        //        out.write(buffer, 0, bytes_read);
        //    whereAt = "after reading";

		serverAlive=true;
//		System.out.println("Todo Esta Bien");
	}catch (java.net.ConnectException se) {
		serverAlive=false;
//		System.err.println("Error de Conexion");

	}catch (javax.net.ssl.SSLHandshakeException se) {
		serverAlive=true;
//		System.err.println("Error De Validacion Certificado");

        }catch (Exception e) {
		serverAlive=false;
//	        System.err.println("Exception for "+urlname+" @ "+whereAt+" = "+e);
        }
        finally {  // Always close the streams, no matter what.
            try { in.close();  out.close(); } catch (Exception e) {}
        }

	return serverAlive;
    }


	public void enviarCorreo(String arg,String[] correos) {

		EmailDto dto_=new EmailDto();
		dto_.setSubject("Monitor Radar+");
		Date fecha_=new Date(System.currentTimeMillis());
		dto_.setMessage(arg+" Hora:"+fecha_.toString());
		ArrayList recipients=new ArrayList();

		for(int k=0;k<correos.length;k++){
		   //System.out.println("correos[k]:"+correos[k]);
      		     recipients.add(correos[k]);
		}
		dto_.setRecipients(recipients);
		dto_.setFrom("radaradmin@computec.com");

		try{
			System.out.println("Enviando Email");
			emailClass.sendEmail(dto_);
			System.out.println("Enviado mail");
		}catch(EmailException ex){
			log.error(nombreGlobalUrl+" - "+ex.getMessage());
			 ex.printStackTrace();
		}
	}

    public static void main(String[] args) {
        new Tray(args);
    }



}
